/**
 * $Id$ Copyright 2009-2012 Oak Pacific Interactive. All rights reserved.
 */
package com.shuqi.common.utils;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import com.shuqi.common.Config;

public class BookBagUtil {

    private final static int BUFFER = 2048;

    /** OOM多发地带 */
    public static ByteArrayOutputStream decode2Zip(String src_file, String key) {
        long n = 0;
        File f = new File(src_file);
        FileInputStream in = null;
        FileInputStream fin = null;
        FileInputStream fin2 = null;
        ByteArrayInputStream bis = null;
        ByteArrayOutputStream bos = null;
        try {
            fin = new FileInputStream(f);
            fin2 = new FileInputStream(f);
            in = new FileInputStream(src_file);
            byte[] keybuffer = new byte[128];// 必须是128 ，新解码规则的要求
            n = in.read(keybuffer, 0, 17);
            String head = new String(keybuffer, 0, 17);
            if (head != null && "shuqireaderbag1.0".equals(head)) {
                /**
                 * 新的解码规则 去掉开头的shuqireaderbag1.0，占17byte, 再过128byte去掉一个混淆的int
                 */
                ByteArrayOutputStream iibos = new ByteArrayOutputStream();
                int i = -1;
                while ((i = in.read(keybuffer)) != -1) {
                    iibos.write(keybuffer, 0, i);
                    n = in.skip(1);
                }
                iibos.flush();
                return iibos;
            } else {
                String sn = key;
                int pos = 0;
                int len = 0;
                ByteArrayOutputStream ppos = new ByteArrayOutputStream();
                byte[] buffer = new byte[BUFFER];
                byte[] tail = new byte[BUFFER];
                byte[] tmp = new byte[BUFFER];
                int size = -1;
                boolean flag = true;
                /**
                 * sn=1 2 9 2391973050571 位置 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 编码前 a b c d
                 * e f g h i j k l m n o p 编码后 a 1 b c 2 d e f g h i j k l 9 m n o
                 * 之后再将头部数据放置尾部，完成了加密 解密就是将尾部数据放置头部，并去掉混淆字符
                 */
                int sum = 0;// 尾部长度
                for (int i = 0; i < sn.length(); i++) {
                    sum += Integer.parseInt(sn.substring(i, i + 1));
                    sum++;
                }
                int fsize = (int) f.length();
                int need2skip = fsize - sum;// 需要读取的正常编码的前半部分长度
                n = fin.skip(need2skip);// 跳过这个长度
                size = fin.read(tail);// 读取尾部
                ppos.write(tail, 0, size);// 将尾部写到新流的头部

                int overage = fsize % BUFFER;// 每段BUFFER
                                             // 2048长,最后一段剩下overage长,如果这个长度大于等于尾部需要忽略的长度sum,
                                             // 就最后一节中读取overage-sum即可，如果overage小于要忽略的长度，则要从倒数第二节截取一部分，抛弃最后一节
                boolean can_be_read = false;
                while ((size = fin2.read(buffer)) != -1) {
                    // Log4an.d("overage", overage+"");
                    // Log4an.d("sum", sum+"");
                    if (overage >= sum) {
                        // Log4an.d("size", size+"");
                        if (size != BUFFER) {// 说明读到最后一段了
                            // Log4an.d("size-sum", (size-sum)+"");
                            ppos.write(buffer, 0, size - sum);
                        } else {
                            ppos.write(buffer, 0, size);
                        }
                    } else {
                        if (can_be_read) {
                            /*
                             * 例如:sum = 80 overage=60 [_____] [_____]
                             */
                            if (size != BUFFER) {// 说明独到最后一段了
                                // System.out.println("overage<sum ");
                                // System.out.println(tmp.length + " @@ " +
                                // (size-(sum-overage)));
                                ppos.write(tmp, 0, size - (sum - overage));
                                break;
                            } else {
                                ppos.write(tmp, 0, size);
                            }
                        }
                        tmp = buffer;
                        can_be_read = true;
                    }
                }
                bis = new ByteArrayInputStream(ppos.toByteArray());
                bos = new ByteArrayOutputStream();
                while ((size = bis.read(buffer)) != -1) {

                    if (flag) {
                        for (int i = 0; i < sn.length(); i++) {
                            String c = sn.substring(i, i + 1);
                            len = Integer.parseInt(c);
                            bos.write(buffer, pos, len);
                            pos += (len + 1);
                        }
                        len = buffer.length - pos;
                        bos.write(buffer, pos, len);
                        flag = false;
                    } else {
                        bos.write(buffer, 0, size);
                    }
                }

                return bos;
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (OutOfMemoryError e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (fin != null) {
                    fin.close();
                }
                if (fin2 != null) {
                    fin2.close();
                }
                if (bis != null) {
                    bis.close();
                }
                if (bos != null) {
                    bos.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (n > 0) {
            return null;
        }
        return null;
    }

    public static ByteArrayInputStream unzip(ByteArrayOutputStream baos_zip, String str) {
        ByteArrayInputStream pis =  null;
        ZipInputStream zis = null;
        try {
            pis = new ByteArrayInputStream(baos_zip.toByteArray());
            zis = new ZipInputStream(pis);
            ZipEntry entry;
            while ((entry = zis.getNextEntry()) != null) {
                if (!entry.toString().equals(str)) {
                    continue;
                }

                ByteArrayOutputStream baos_entry = new ByteArrayOutputStream();
                byte[] buffer = new byte[BUFFER];
                int count = 0;
                // TODO 需要修复的bug,文件下载不完全则会导致不返回-1
                while ((count = zis.read(buffer)) > 0) {// != -1
                    baos_entry.write(buffer, 0, count);
                }
                ByteArrayInputStream istr = new ByteArrayInputStream(baos_entry.toByteArray());
                return istr;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (pis != null) {
                    pis.close();
                }
                if (zis != null) {
                    zis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
    
    /***
     * 删除书包文件
     * @param bookId
     */
    public static void deletBookBagData(final String bookId){
      //删除书包文件
        File floder = new File(Config.BOOKBAG_PATH);
        FilenameFilter filter = new FilenameFilter() {
            @Override
            public boolean accept(File dir, String filename) {
                return filename.startsWith(bookId+"_") && filename.endsWith(".sqb");
            }
        };
        try {
            File[] files = floder.listFiles(filter);
            if(files!=null && files.length>0){
                Log4an.e("", "will delete num = "+files.length);
                for (int i = 0; i < files.length; i++) {
                    if(files[i].isFile()){
                        boolean delete = files[i].delete();
                        Log4an.e("", "delete "+delete+" fileName="+files[i].getName());
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    

}
